package com.trace.learn.transmittable;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * TransmittableThreadLocal线程池传递
 * @author chenxin
 * @time 2017-03-19-09:20
 */
public class TransmittableExecutorTest {
    /**
     *TransmittableThreadLocal 与 InheritableThreadLocal 用的同一个map ThreadLocal.ThreadLocalMap inheritableThreadLocals
     * 只是key不同，key为 XXXThreadLocal
     */

    private static TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();

    private static InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<String>();

    public static void main(String[] args) throws Exception{

        parent.set("value-set-in-parent");









        inheritableThreadLocal.set("value-set-in-parent-inheritableThreadLocal");

        ExecutorService executorService = Executors.newFixedThreadPool(2);

        Runnable runnable1 = new MyRunnable();
        executorService.execute(runnable1);

        Runnable runnable2 = new MyRunnable();
        Future<Void> future = (Future<Void>) executorService.submit(runnable2);
        future.get();

        System.out.println(Thread.currentThread().getName() + " " + parent.get());

        /**
         * 重新设置主线程的threadLocal， 看线程池中缓存的线程的threadLocal是否会变，即是否重新获取
         */
//        parent.set("value-set-in-parent-3");

        inheritableThreadLocal.set("value-set-in-parent-inheritableThreadLocal-3");

        Runnable runnable3 = new MyRunnable();

        Runnable ttlRunnable = TtlRunnable.get(runnable3);

        // 不进行包装， 则主线程新设置的值无法传递到线程池， 因为线程池中的线程已缓存
//        Future<Void> future3 = (Future<Void>) executorService.submit(runnable3);

        Future<Void> future3 = (Future<Void>) executorService.submit(ttlRunnable);
        future3.get();

        System.out.println(Thread.currentThread().getName() + " " + parent.get());


    }

    private static class MyRunnable implements Runnable{
        @Override public void run() {
            System.out.println(Thread.currentThread().getName() + " runnable get =" + parent.get());

            System.out.println(Thread.currentThread().getName() + " runnable get =" + inheritableThreadLocal.get());

            /**
             * 线程池重新设置值，在主线程无法访问到
             */
//            parent.set("MyRunnable Value");
//
//            inheritableThreadLocal.set("inheritableThreadLocal MyRunnable Value");

        }
    }
}
